#include "pch.h"
#include "DesktopFrameWin.h"


DesktopFrameWin::DesktopFrameWin(DesktopSize size,
	int stride,
	uint8_t* data,
	std::unique_ptr<SharedMemory> shared_memory,
	HBITMAP bitmap)
	: DesktopFrame(size, stride, data, shared_memory.get()),
	bitmap_(bitmap),
	owned_shared_memory_(std::move(shared_memory)) {
}

DesktopFrameWin::~DesktopFrameWin() {
	DeleteObject(bitmap_);
}

std::unique_ptr<DesktopFrameWin> DesktopFrameWin::Create(
	DesktopSize size,
	SharedMemoryFactory* shared_memory_factory,
	HDC hdc) {
	int bytes_per_row = size.width() * kBytesPerPixel;
	int buffer_size = bytes_per_row * size.height();

	BITMAPINFO bmi;
	ZeroMemory(&bmi, sizeof(bmi));
	bmi.bmiHeader.biHeight = -size.height();
	bmi.bmiHeader.biWidth = size.width();
	bmi.bmiHeader.biPlanes = 1;
	bmi.bmiHeader.biBitCount = DesktopFrameWin::kBytesPerPixel * 8;
	bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
	bmi.bmiHeader.biSizeImage = bytes_per_row * size.height();

	std::unique_ptr<SharedMemory> shared_memory;
	HANDLE section_handle = nullptr;
	if (shared_memory_factory) {
		shared_memory = shared_memory_factory->CreateSharedMemory(buffer_size);
		section_handle = shared_memory->handle();
	}
	void* data = nullptr;
	HBITMAP bitmap =
		CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, &data, section_handle, 0);
	if (!bitmap) {
		return nullptr;
	}

	return std::unique_ptr<DesktopFrameWin>(
		new DesktopFrameWin(size, bytes_per_row, reinterpret_cast<uint8_t*>(data),
			std::move(shared_memory), bitmap));
}
